#include "ChatGrpcClient.h"
#include "configMgr.h"
ChatGrpcClient& ChatGrpcClient::GetInst()
{
	static ChatGrpcClient instance;
	return instance;
}

message::AddFriendRsp ChatGrpcClient::NotifyAddFriend(std::string server_ip, const message::AddFriendReq& req)
{
	message::AddFriendRsp rsp;
	Defer defer([&rsp,&req]() {
		rsp.set_error(ErrorCodes::Success);
		rsp.set_applyuid(req.applyuid());
		rsp.set_touid(req.touid());
		});
	auto find_iter = _pool.find(server_ip);
	if (find_iter==_pool.end())
	{
		return rsp;
	}

	auto& pool = find_iter->second;
	grpc::ClientContext context;
	auto stub = pool->GetConnection();
	grpc::Status status = stub->NotifyAddFriend(&context, req, &rsp);
	Defer defercon([&stub, this, &pool]() {
		pool->ReturnConnection(std::move(stub));
		});

	if (!status.ok())
	{
		rsp.set_error(ErrorCodes::RPCFailed);
		return rsp;
	}
	return message::AddFriendRsp();
}

message::AuthFriendRsp ChatGrpcClient::NotifyAuthFriend(std::string server_ip, const message::AuthFriendReq& req)
{
	message::AuthFriendRsp rsp;
	rsp.set_error(ErrorCodes::Success);

	Defer defer([&rsp, &req]() {
		rsp.set_fromuid(req.fromuid());
		rsp.set_touid(req.touid());
		});

	auto find_iter = _pool.find(server_ip);
	if (find_iter == _pool.end()) {
		return rsp;
	}

	auto& pool = find_iter->second;
	grpc::ClientContext context;
	auto stub = pool->GetConnection();
	grpc::Status status = stub->NotifyAuthFriend(&context, req, &rsp);
	Defer defercon([&stub, this, &pool]() {
		pool->ReturnConnection(std::move(stub));
		});

	if (!status.ok()) {
		rsp.set_error(ErrorCodes::RPCFailed);
		return rsp;
	}

	return rsp;
}

bool ChatGrpcClient::GetBaseInfo(std::string base_key, int uid, std::shared_ptr<UserInfo>& userinfo)
{
	return false;
}

message::TextChatMsgRsp ChatGrpcClient::NotifyTextChatMsg(std::string server_ip, const message::TextChatMsgReq& req, const Json::Value& rtvalue)
{
	message::TextChatMsgRsp rsp;
	rsp.set_error(ErrorCodes::Success);

	Defer defer([&rsp, &req]() {
		rsp.set_fromuid(req.fromuid());
		rsp.set_touid(req.touid());
		for (const auto& text_data : req.textmsgs()) {
			message::TextChatData* new_msg = rsp.add_textmsgs();
			new_msg->set_msgid(text_data.msgid());
			new_msg->set_msgcontent(text_data.msgcontent());
		}

		});

	auto find_iter = _pool.find(server_ip);
	if (find_iter == _pool.end()) {
		return rsp;
	}

	auto& pool = find_iter->second;
	grpc::ClientContext context;
	auto stub = pool->GetConnection();
	grpc::Status status = stub->NotifyTextChatMsg(&context, req, &rsp);
	Defer defercon([&stub, this, &pool]() {
		pool->ReturnConnection(std::move(stub));
		});

	if (!status.ok()) {
		rsp.set_error(ErrorCodes::RPCFailed);
		return rsp;
	}

	return rsp;
}

ChatGrpcClient::ChatGrpcClient() {
	auto& cfg = configMgr::GetInst();
	auto server_list = cfg["PeerServer"]["Servers"];

	std::vector<std::string> words;

	std::stringstream ss(server_list);
	std::string word;

	while (std::getline(ss, word, ',')) {
		words.push_back(word);
	}

	for (auto& word : words) {
		if (cfg[word]["Name"].empty()) {
			continue;
		}
		_pool[cfg[word]["Name"]] = std::make_unique<ChatConPool>(5, cfg[word]["Host"], cfg[word]["Port"]);
	}
}
